bitkeeper revision 1.1159.1.320 (4186495166A8XLekEbNixl7hWUA08w)
authorkaf24@freefall.cl.cam.ac.uk <kaf24@freefall.cl.cam.ac.uk>
Mon, 1 Nov 2004 14:33:53 +0000 (14:33 +0000)
committerkaf24@freefall.cl.cam.ac.uk <kaf24@freefall.cl.cam.ac.uk>
Mon, 1 Nov 2004 14:33:53 +0000 (14:33 +0000)
Clean up softirq handling. All debug keypresses are now deferred to
a softirq handler.

12 files changed:
xen/arch/x86/irq.c
xen/arch/x86/memory.c
xen/arch/x86/pdb-stub.c
xen/common/ac_timer.c
xen/common/keyhandler.c
xen/common/perfc.c
xen/common/schedule.c
xen/common/softirq.c
xen/drivers/char/console.c
xen/include/asm-x86/bitops.h
xen/include/xen/keyhandler.h
xen/include/xen/softirq.h

index 2ed656549c28e07c9bb765c3a67f00b2af96c079..b3534c0df5663635a4742546bf74f6463f1d938e 100644 (file)
@@ -210,16 +210,17 @@ static void __do_IRQ_guest(int irq)
 int pirq_guest_unmask(struct domain *d)
 {
     irq_desc_t    *desc;
-    int            i, j, pirq;
+    unsigned int   i, j, pirq;
     u32            m;
     shared_info_t *s = d->shared_info;
 
     for ( i = 0; i < ARRAY_SIZE(d->pirq_mask); i++ )
     {
         m = d->pirq_mask[i];
-        while ( (j = ffs(m)) != 0 )
+        while ( m != 0 )
         {
-            m &= ~(1 << --j);
+            j = find_first_set_bit(m);
+            m &= ~(1 << j);
             pirq = (i << 5) + j;
             desc = &irq_desc[pirq];
             spin_lock_irq(&desc->lock);
index 410829cc7283c067729ad445c971d2b116081105..39345ed7a36de40167bf269608b23f48e8614daf 100644 (file)
@@ -2261,11 +2261,9 @@ void audit_domains(void)
         audit_domain(d);
 }
 
-void audit_domains_key(unsigned char key, void *dev_id,
-                       struct pt_regs *regs)
+void audit_domains_key(unsigned char key)
 {
-    open_softirq(MEMAUDIT_SOFTIRQ, audit_domains);
-    raise_softirq(MEMAUDIT_SOFTIRQ);
+    audit_domains();
 }
 
 #endif
index 774167c88b3877ba6e21de68529cacc4719082da..a1eb36b0f26b1a020e86d1e393b6aaf7f34af4c0 100644 (file)
@@ -1213,17 +1213,12 @@ int pdb_handle_exception(int exceptionVector,
     return 0;
 }
 
-void __pdb_key_pressed(void)
+void pdb_key_pressed(unsigned char key)
 {
     struct pt_regs *regs = (struct pt_regs *)get_execution_context();
     pdb_handle_exception(KEYPRESS_EXCEPTION, regs);
 }
 
-void pdb_key_pressed(u_char key, void *dev_id, struct pt_regs *regs) 
-{
-    raise_softirq(DEBUGGER_SOFTIRQ);
-}
-
 void initialize_pdb()
 {
     extern char opt_pdb[];
@@ -1254,7 +1249,6 @@ void initialize_pdb()
     /* Acknowledge any spurious GDB packets. */
     pdb_put_char('+');
 
-    open_softirq(DEBUGGER_SOFTIRQ, __pdb_key_pressed);
     add_key_handler('D', pdb_key_pressed, "enter pervasive debugger");
 
     pdb_initialized = 1;
index 658fea3457680db2223eeb537922c03cf75e394b..ddef6d33c391e86599e2674e1ebd2eddbd2f595d 100644 (file)
@@ -244,7 +244,7 @@ static void ac_timer_softirq_action(void)
 }
 
 
-static void dump_timerq(u_char key, void *dev_id, struct pt_regs *regs)
+static void dump_timerq(unsigned char key)
 {
     struct ac_timer *t;
     unsigned long    flags; 
index 48860e43c92bb357dfab7b13a30961057327a956..96ac0d6bd63f234be3e1e2222750d7bc916ed408 100644 (file)
@@ -5,6 +5,7 @@
 #include <xen/console.h>
 #include <xen/serial.h>
 #include <xen/sched.h>
+#include <xen/softirq.h>
 
 #define KEY_MAX 256
 #define STR_MAX  64
@@ -14,6 +15,22 @@ static struct {
     char         desc[STR_MAX]; 
 } key_table[KEY_MAX]; 
 
+static unsigned char keypress_key;
+
+void keypress_softirq(void)
+{
+    key_handler  *h;
+    unsigned char key = keypress_key;
+    if ( (h = key_table[key].handler) != NULL )
+        (*h)(key);
+}
+
+void handle_keypress(unsigned char key)
+{
+    keypress_key = key;
+    raise_softirq(KEYPRESS_SOFTIRQ);
+}
+
 void add_key_handler(unsigned char key, key_handler *handler, char *desc)
 {
     key_table[key].handler = handler; 
@@ -21,13 +38,7 @@ void add_key_handler(unsigned char key, key_handler *handler, char *desc)
     key_table[key].desc[STR_MAX-1] = '\0'; 
 }
 
-key_handler *get_key_handler(unsigned char key)
-{
-    return key_table[key].handler; 
-}
-
-static void show_handlers(unsigned char key, void *dev_id,
-                          struct pt_regs *regs)
+static void show_handlers(unsigned char key)
 {
     int i; 
     printk("'%c' pressed -> showing installed handlers\n", key);
@@ -39,23 +50,21 @@ static void show_handlers(unsigned char key, void *dev_id,
 }
 
 
-static void dump_registers(unsigned char key, void *dev_id,
-                           struct pt_regs *regs)
+static void dump_registers(unsigned char key)
 {
+    struct pt_regs *regs = (struct pt_regs *)get_execution_context();
     extern void show_registers(struct pt_regs *regs); 
     printk("'%c' pressed -> dumping registers\n", key); 
     show_registers(regs); 
 }
 
-static void halt_machine(unsigned char key, void *dev_id,
-                         struct pt_regs *regs) 
+static void halt_machine(unsigned char key)
 {
     printk("'%c' pressed -> rebooting machine\n", key); 
     machine_restart(NULL); 
 }
 
-void do_task_queues(unsigned char key, void *dev_id,
-                    struct pt_regs *regs) 
+void do_task_queues(unsigned char key)
 {
     unsigned long  flags;
     struct domain *d;
@@ -102,26 +111,22 @@ void do_task_queues(unsigned char key, void *dev_id,
     read_unlock_irqrestore(&tasklist_lock, flags); 
 }
 
-extern void dump_runq(unsigned char key, void *dev_id, 
-                      struct pt_regs *regs);
-extern void print_sched_histo(unsigned char key, void *dev_id, 
-                              struct pt_regs *regs);
-extern void reset_sched_histo(unsigned char key, void *dev_id, 
-                              struct pt_regs *regs);
+extern void dump_runq(unsigned char key);
+extern void print_sched_histo(unsigned char key);
+extern void reset_sched_histo(unsigned char key);
 #ifndef NDEBUG
-extern void audit_domains_key(unsigned char key, void *dev_id,
-                           struct pt_regs *regs);
+extern void audit_domains_key(unsigned char key);
 #endif
 
 #ifdef PERF_COUNTERS
-extern void perfc_printall(unsigned char key, void *dev_id,
-                           struct pt_regs *regs);
-extern void perfc_reset(unsigned char key, void *dev_id,
-                        struct pt_regs *regs);
+extern void perfc_printall(unsigned char key);
+extern void perfc_reset(unsigned char key);
 #endif
 
 void initialize_keytable(void)
 {
+    open_softirq(KEYPRESS_SOFTIRQ, keypress_softirq);
+
     add_key_handler('d', dump_registers, "dump registers"); 
     add_key_handler('h', show_handlers, "show this message");
     add_key_handler('l', print_sched_histo, "print sched latency histogram");
index 631e81787c0598388194f6f26b966c036faacebd..3a05c2e0719539e844e5dac2ef93b289ad4f3b18 100644 (file)
@@ -31,7 +31,7 @@ static struct {
 
 struct perfcounter_t perfcounters;
 
-void perfc_printall(u_char key, void *dev_id, struct pt_regs *regs)
+void perfc_printall(unsigned char key)
 {
     int i, j, sum;
     s_time_t now = NOW();
@@ -73,7 +73,7 @@ void perfc_printall(u_char key, void *dev_id, struct pt_regs *regs)
     }
 }
 
-void perfc_reset(u_char key, void *dev_id, struct pt_regs *regs)
+void perfc_reset(unsigned char key)
 {
     int i, j, sum;
     s_time_t now = NOW();
@@ -82,7 +82,7 @@ void perfc_reset(u_char key, void *dev_id, struct pt_regs *regs)
     printk("Xen performance counters RESET (now = 0x%08X:%08X)\n",
            (u32)(now>>32), (u32)now);
 
-    // leave STATUS counters alone -- don't reset
+    /* leave STATUS counters alone -- don't reset */
 
     for ( i = 0; i < NR_PERFCTRS; i++ ) 
     {
index 138234104d591279fbf67afa6775f09d4b4ea066..c037c9e17753546f153186f7c75318870ce468e4 100644 (file)
@@ -544,7 +544,7 @@ void schedulers_start(void)
 }
 
 
-void dump_runq(u_char key, void *dev_id, struct pt_regs *regs)
+void dump_runq(unsigned char key)
 {
     s_time_t      now = NOW();
     int           i;
@@ -568,7 +568,7 @@ void dump_runq(u_char key, void *dev_id, struct pt_regs *regs)
 }
 
 #if defined(WAKE_HISTO) || defined(BLOCKTIME_HISTO)
-void print_sched_histo(u_char key, void *dev_id, struct pt_regs *regs)
+void print_sched_histo(unsigned char key)
 {
     int i, j, k;
     for ( k = 0; k < smp_num_cpus; k++ )
@@ -591,7 +591,7 @@ void print_sched_histo(u_char key, void *dev_id, struct pt_regs *regs)
     }
       
 }
-void reset_sched_histo(u_char key, void *dev_id, struct pt_regs *regs)
+void reset_sched_histo(unsigned char key)
 {
     int i, j;
     for ( j = 0; j < smp_num_cpus; j++ )
@@ -599,10 +599,6 @@ void reset_sched_histo(u_char key, void *dev_id, struct pt_regs *regs)
             schedule_data[j].hist[i] = 0;
 }
 #else
-void print_sched_histo(u_char key, void *dev_id, struct pt_regs *regs)
-{
-}
-void reset_sched_histo(u_char key, void *dev_id, struct pt_regs *regs)
-{
-}
+void print_sched_histo(unsigned char key) { }
+void reset_sched_histo(unsigned char key) { }
 #endif
index 3e1472e94abf4a5138968ee07ce9fccf9582da99..166a8163c1f03de402593d60ac32d8bdaee6eecf 100644 (file)
@@ -21,19 +21,13 @@ static softirq_handler softirq_handlers[NR_SOFTIRQS] __cacheline_aligned;
 
 asmlinkage void do_softirq()
 {
-    unsigned int pending, cpu = smp_processor_id();
-    softirq_handler *h;
+    unsigned int i, pending, cpu = smp_processor_id();
 
-    while ( (pending = xchg(&softirq_pending(cpu), 0)) != 0 )
+    while ( (pending = softirq_pending(cpu)) != 0 )
     {
-        h = softirq_handlers;
-        while ( pending )
-        {
-            if ( pending & 1 )
-                (*h)();
-            h++;
-            pending >>= 1;
-        }
+        i = find_first_set_bit(pending);
+        clear_bit(i, &softirq_pending(cpu));
+        (*softirq_handlers[i])();
     }
 }
 
index 350cf09cbd5c9dc05d41003864f272eb1268e470..a6a979284cf288bd648287b8a5e41103a7e3fc1f 100644 (file)
@@ -245,22 +245,20 @@ static void switch_serial_input(void)
 
 static void __serial_rx(unsigned char c, struct pt_regs *regs)
 {
-    key_handler *handler;
-    struct domain *p;
+    struct domain *d;
 
     if ( xen_rx )
     {
-        if ( (handler = get_key_handler(c)) != NULL )
-            (*handler)(c, NULL, regs);
+        handle_keypress(c);
     }
     else if ( (serial_rx_prod-serial_rx_cons) != SERIAL_RX_SIZE )
     {
         serial_rx_ring[SERIAL_RX_MASK(serial_rx_prod)] = c;
         if ( serial_rx_prod++ == serial_rx_cons )
         {
-            p = find_domain_by_id(0); /* only DOM0 reads the serial buffer */
-            send_guest_virq(p, VIRQ_CONSOLE);
-            put_domain(p);
+            d = find_domain_by_id(0); /* only DOM0 reads the serial buffer */
+            send_guest_virq(d, VIRQ_CONSOLE);
+            put_domain(d);
         }
     }
 }
index 58ae424e54f839c8d9c86e148a73847019c6b20c..cf98f2e1182b8ed0422bc7830020730077aeb323 100644 (file)
@@ -340,6 +340,27 @@ static __inline__ int ffs(int x)
        return r+1;
 }
 
+/*
+ * These are the preferred 'find first' functions in Xen.
+ * Both return the appropriate bit index, with the l.s.b. having index 0.
+ * If an appropriate bit is not found then the result is undefined.
+ */
+static __inline__ unsigned long find_first_clear_bit(unsigned long word)
+{
+       __asm__("bsf"__OS" %1,%0"
+               :"=r" (word)
+               :"r" (~word));
+       return word;
+}
+
+static __inline__ unsigned long find_first_set_bit(unsigned long word)
+{
+       __asm__("bsf"__OS" %1,%0"
+               :"=r" (word)
+               :"r" (word));
+       return word;
+}
+
 /**
  * hweightN - returns the hamming weight of a N-bit word
  * @x: the word to weigh
index 03aa53bab5948e53fa4cac9b070db17dcc5484d9..d12621ef335dbd44eef30d5e5795a2d98d52bd43 100644 (file)
@@ -6,11 +6,10 @@
 */
 #include <xen/sched.h>
 
-typedef void key_handler(unsigned char key, void *dev_id, 
-                        struct pt_regs *regs); 
+typedef void key_handler(unsigned char key);
 
 extern void add_key_handler(unsigned char key, 
                            key_handler *handler, char *desc); 
 
-extern key_handler *get_key_handler(unsigned char key); 
+extern void handle_keypress(unsigned char key);
 
index 7bf05b9f466e0eb99a5fb7de5bfa1173afbd0c78..6180dae775f0ffa9555d2a272f3ff168e1691492 100644 (file)
@@ -1,13 +1,13 @@
 #ifndef __XEN_SOFTIRQ_H__
 #define __XEN_SOFTIRQ_H__
 
+/* Common softirqs come first in the following list. */
 #define AC_TIMER_SOFTIRQ                  0
-#define NEW_TLBFLUSH_CLOCK_PERIOD_SOFTIRQ 1
-#define DEBUGGER_SOFTIRQ                  2
-#define NMI_SOFTIRQ                       3
-#define SCHEDULE_SOFTIRQ                  4
-#define MEMAUDIT_SOFTIRQ                  5
-#define NR_SOFTIRQS                       6
+#define SCHEDULE_SOFTIRQ                  1
+#define NEW_TLBFLUSH_CLOCK_PERIOD_SOFTIRQ 2
+#define KEYPRESS_SOFTIRQ                  3
+#define NMI_SOFTIRQ                       4
+#define NR_SOFTIRQS                       5
 
 #ifndef __ASSEMBLY__